package br.unicamp.ic.lis.dbvapicasestudy;

import java.util.List;

import org.genericspatialdao.utils.SpatialUtils;

import br.unicamp.ic.lis.dbvmsapi.controller.APIController;
import br.unicamp.ic.lis.dbvmsapi.controller.impl.APIControllerImpl;
import br.unicamp.ic.lis.dbvmsapi.domain.AbstractPhysicalVersion;
import br.unicamp.ic.lis.dbvmsapi.domain.DBV;
import br.unicamp.ic.lis.dbvmsapi.domain.GeometryPV;
import br.unicamp.ic.lis.dbvmsapi.domain.LogicalVersion;
import br.unicamp.ic.lis.dbvmsapi.domain.MultiversionObject;
import br.unicamp.ic.lis.dbvmsapi.domain.Scale;
import br.unicamp.ic.lis.dbvmsapi.domain.Scale.ScaleType;

import com.vividsolutions.jts.geom.Geometry;

public class Main {

	private static final int SRID = 4326;

	// MultiversionObjects
	private MultiversionObject mvoCitySection;
	private MultiversionObject mvoHorizontalRoad;
	private MultiversionObject mvoVerticalRoad1;
	private MultiversionObject mvoVerticalRoad2;

	// AbstractPhysicalVersions
	private AbstractPhysicalVersion<Geometry> pv1;
	private AbstractPhysicalVersion<Geometry> pv2;
	private AbstractPhysicalVersion<Geometry> pv3;
	private AbstractPhysicalVersion<Geometry> pv4;
	private AbstractPhysicalVersion<Geometry> pv5;
	private AbstractPhysicalVersion<Geometry> pv6;
	private AbstractPhysicalVersion<Geometry> pv7;
	private AbstractPhysicalVersion<Geometry> pv8;
	private AbstractPhysicalVersion<Geometry> pv9;
	private AbstractPhysicalVersion<Geometry> pv10;
	private AbstractPhysicalVersion<Geometry> pv11;

	// Scales
	private Scale spatialScale10000;
	private Scale spatialScale20000;
	private Scale spatialScale50000;

	private List<DBV> rootScenario;
	private List<DBV> scenario0_1;
	private List<DBV> scenario0_1_1;
	private List<DBV> scenario0_1_2;

	private APIController api;

	public static void main(String[] args) {
		Main m = new Main();
		m.caseStudy();
	}

	public void getLVs() {

	}

	public void caseStudy() {
		// SETUP
		setupScale();
		setupMultiversionObjectAndAbstractPhysicalVersionObject();

		// insertions of objects and physical versions
		api = new APIControllerImpl();

		api.addMultiversionObject(mvoCitySection, mvoHorizontalRoad,
				mvoVerticalRoad1, mvoVerticalRoad2);

		api.addScale(spatialScale10000, spatialScale20000, spatialScale50000);

		// ACTION
		// creation of derivation trees
		rootScenario = api.getScenario("0");

		//
		// version 0.1
		//
		DBV d01 = api.createDBVFrom(rootScenario.get(0));
		scenario0_1 = api.getScenario("0.1");
		LogicalVersion lv1 = new LogicalVersion(mvoCitySection,
				scenario0_1.get(0), pv1);
		api.addLogicalVersion(lv1);
		LogicalVersion lv2 = new LogicalVersion(mvoCitySection,
				scenario0_1.get(1), pv2);
		api.addLogicalVersion(lv2);
		LogicalVersion lv3 = new LogicalVersion(mvoCitySection,
				scenario0_1.get(2), pv3);
		api.addLogicalVersion(lv3);
		print(scenario0_1);

		//
		// version 0.1.1
		//
		DBV d011 = api.createDBVFrom(scenario0_1.get(1));
		scenario0_1_1 = api.getScenario("0.1.1");
		LogicalVersion lv4 = new LogicalVersion(mvoHorizontalRoad,
				scenario0_1_1.get(0), pv4);
		api.addLogicalVersion(lv4);
		LogicalVersion lv5 = new LogicalVersion(mvoHorizontalRoad,
				scenario0_1_1.get(1), pv5);
		api.addLogicalVersion(lv5);
		LogicalVersion lv6 = new LogicalVersion(mvoHorizontalRoad,
				scenario0_1_1.get(2), pv6);
		api.addLogicalVersion(lv6);
		print(scenario0_1_1);

		//
		// version 0.1.2
		//
		DBV d012 = api.createDBVFrom(scenario0_1.get(0));
		scenario0_1_2 = api.getScenario("0.1.2");
		LogicalVersion lv7 = new LogicalVersion(mvoVerticalRoad1,
				scenario0_1_2.get(0), pv7);
		api.addLogicalVersion(lv7);
		LogicalVersion lv8 = new LogicalVersion(mvoVerticalRoad1,
				scenario0_1_2.get(1), pv8);
		api.addLogicalVersion(lv8);
		LogicalVersion lv9 = new LogicalVersion(mvoVerticalRoad1,
				scenario0_1_2.get(2), pv9);
		api.addLogicalVersion(lv9);
		LogicalVersion lv10 = new LogicalVersion(mvoVerticalRoad2,
				scenario0_1_2.get(0), pv10);
		api.addLogicalVersion(lv10);
		LogicalVersion lv11 = new LogicalVersion(mvoVerticalRoad2,
				scenario0_1_2.get(1), pv11);
		api.addLogicalVersion(lv11);
		LogicalVersion lv12 = new LogicalVersion(mvoVerticalRoad2,
				scenario0_1_2.get(2), pv9);
		api.addLogicalVersion(lv12);
		print(scenario0_1_2);

		print(scenario0_1);
		print(scenario0_1_1);
		print(scenario0_1_2);
		api.close();
		/*
		 * System.out.println(); System.out.println("RESULTS:");
		 * System.out.println("Workspace 0:   " + rootWorkspace);
		 * System.out.println("Workspace 1:   " + workspace1);
		 * System.out.println("Workspace 2:   " + workspace2);
		 * System.out.println("Workspace 2.1: " + workspace21);
		 */
	}

	private void setupScale() {
		spatialScale10000 = new Scale(null, ScaleType.SPATIAL_SCALE, "1:10000");
		spatialScale20000 = new Scale(spatialScale10000,
				ScaleType.SPATIAL_SCALE, "1:20000");
		spatialScale50000 = new Scale(spatialScale20000,
				ScaleType.SPATIAL_SCALE, "1:50000");
	}

	private void setupMultiversionObjectAndAbstractPhysicalVersionObject() {
		// City section
		mvoCitySection = new MultiversionObject();
		mvoCitySection.setTitle("city section");
		// City section 1:10000
		pv1 = new GeometryPV(SpatialUtils.generateLongLatPoint(SRID));
		// pv1.setValue(SpatialUtils.generateLongLatPoint(SRID));
		// City section 1:20000
		pv2 = new GeometryPV(SpatialUtils.generateLongLatPoint(SRID));
		// City section 1:50000
		pv3 = new GeometryPV(SpatialUtils.generateLongLatPoint(SRID));
		mvoCitySection.addPhysicalVersion(pv1, pv2, pv3);

		// Horizontal road
		mvoHorizontalRoad = new MultiversionObject();
		mvoHorizontalRoad.setTitle("horizontal road");
		// Horizontal road 1:10000
		pv4 = new GeometryPV(SpatialUtils.generateLongLatPoint(SRID));
		// Horizontal road 1:20000
		pv5 = new GeometryPV(SpatialUtils.generateLongLatPoint(SRID));
		// Horizontal road 1:50000
		pv6 = new GeometryPV(SpatialUtils.generateLongLatPoint(SRID));
		mvoHorizontalRoad.addPhysicalVersion(pv4, pv5, pv6);

		// Vertical road 1
		mvoVerticalRoad1 = new MultiversionObject();
		mvoVerticalRoad1.setTitle("vertical road 1");
		// Vertical road 1 1:10000
		pv7 = new GeometryPV(SpatialUtils.generateLongLatPoint(SRID));
		// Vertical road 1 1:20000
		pv8 = new GeometryPV(SpatialUtils.generateLongLatPoint(SRID));
		// Vertical road 1 1:50000
		pv11 = new GeometryPV(SpatialUtils.generateLongLatPoint(SRID));
		mvoVerticalRoad1.addPhysicalVersion(pv7, pv8, pv11);

		// Vertical road 2
		mvoVerticalRoad2 = new MultiversionObject();
		mvoVerticalRoad2.setTitle("vertical road 2");
		// Vertical road 2 1:10000
		pv9 = new GeometryPV(SpatialUtils.generateLongLatPoint(SRID));
		// Vertical road 2 1:20000
		pv10 = new GeometryPV(SpatialUtils.generateLongLatPoint(SRID));
		// Vertical road 2 1:50000
		// p11
		mvoVerticalRoad2.addPhysicalVersion(pv9, pv10, pv11);
	}

	public void print(List<DBV> workspace) {
		List<LogicalVersion> dbv10k = api.getLogicalVersions(workspace.get(0));
		List<LogicalVersion> dbv20k = api.getLogicalVersions(workspace.get(1));
		List<LogicalVersion> dbv50k = api.getLogicalVersions(workspace.get(2));
		System.out
				.println("**********************************************************************************************************************");
		System.out.println(workspace.get(0).getStamp() + " - "
				+ workspace.get(0).getScale().getValue() + ": " + dbv10k);
		System.out.println(workspace.get(1).getStamp() + " - "
				+ workspace.get(1).getScale().getValue() + ": " + dbv20k);
		System.out.println(workspace.get(2).getStamp() + " - "
				+ workspace.get(2).getScale().getValue() + ": " + dbv50k);
		System.out
				.println("**********************************************************************************************************************");
	}

}
